#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI Client Wrapper
Provides unified interface for OpenAI and Anthropic APIs
"""
from __future__ import annotations

import os
from enum import Enum
from typing import Any


class AIProvider(str, Enum):
    """Supported AI providers"""

    OPENAI = "openai"
    ANTHROPIC = "anthropic"
    MOCK = "mock"


class AIClient:
    """
    Unified AI client for code analysis and diagnostics

    Supports:
    - OpenAI (GPT-4, GPT-3.5)
    - Anthropic (Claude)
    - Mock mode (for testing without API keys)
    """

    def __init__(self, provider: AIProvider = AIProvider.MOCK) -> None:
        """
        Initialize AI client

        Args:
            provider: AI provider to use
        """
        self.provider = provider
        self._client: Any = None

        if provider == AIProvider.OPENAI:
            self._init_openai()
        elif provider == AIProvider.ANTHROPIC:
            self._init_anthropic()
        elif provider == AIProvider.MOCK:
            self._init_mock()

    def _init_openai(self) -> None:
        """Initialize OpenAI client"""
        try:
            import openai

            api_key = os.getenv("OPENAI_API_KEY")
            if not api_key:
                raise ValueError("OPENAI_API_KEY environment variable not set")

            openai.api_key = api_key
            self._client = openai
        except ImportError:
            raise ImportError(
                "OpenAI package not installed. Install with: pip install openai"
            )

    def _init_anthropic(self) -> None:
        """Initialize Anthropic client"""
        try:
            import anthropic

            api_key = os.getenv("ANTHROPIC_API_KEY")
            if not api_key:
                raise ValueError("ANTHROPIC_API_KEY environment variable not set")

            self._client = anthropic.Anthropic(api_key=api_key)
        except ImportError:
            raise ImportError(
                "Anthropic package not installed. Install with: pip install anthropic"
            )

    def _init_mock(self) -> None:
        """Initialize mock client for testing"""
        self._client = None

    def diagnose_error(
        self,
        error_log: str,
        context: str = "",
        max_tokens: int = 1000,
    ) -> dict[str, Any]:
        """
        Diagnose error using AI

        Args:
            error_log: Error log content
            context: Additional context (code snippets, etc.)
            max_tokens: Maximum tokens for response

        Returns:
            Dictionary with diagnosis results
        """
        if self.provider == AIProvider.MOCK:
            return self._mock_diagnose(error_log)

        prompt = self._build_diagnostic_prompt(error_log, context)

        if self.provider == AIProvider.OPENAI:
            return self._openai_diagnose(prompt, max_tokens)
        elif self.provider == AIProvider.ANTHROPIC:
            return self._anthropic_diagnose(prompt, max_tokens)

        raise ValueError(f"Unsupported provider: {self.provider}")

    def _build_diagnostic_prompt(self, error_log: str, context: str) -> str:
        """Build diagnostic prompt"""
        prompt = f"""You are a Python code quality expert. Analyze the following error log and provide:

1. Root cause analysis
2. Specific fix recommendations
3. Prevention strategies

Error Log:
```
{error_log}
```
"""

        if context:
            prompt += f"\nAdditional Context:\n```\n{context}\n```"

        prompt += "\n\nProvide a structured JSON response with keys: root_cause, fixes, prevention."

        return prompt

    def _openai_diagnose(self, prompt: str, max_tokens: int) -> dict[str, Any]:
        """Diagnose using OpenAI"""
        try:
            response = self._client.ChatCompletion.create(
                model="gpt-4",
                messages=[
                    {"role": "system", "content": "You are a Python expert."},
                    {"role": "user", "content": prompt},
                ],
                max_tokens=max_tokens,
                temperature=0.3,
            )

            content = response.choices[0].message.content

            return {
                "status": "success",
                "provider": "openai",
                "diagnosis": content,
                "usage": response.usage._asdict(),
            }
        except Exception as e:
            return {
                "status": "error",
                "provider": "openai",
                "error": str(e),
            }

    def _anthropic_diagnose(self, prompt: str, max_tokens: int) -> dict[str, Any]:
        """Diagnose using Anthropic Claude"""
        try:
            message = self._client.messages.create(
                model="claude-3-sonnet-20240229",
                max_tokens=max_tokens,
                messages=[{"role": "user", "content": prompt}],
            )

            content = message.content[0].text

            return {
                "status": "success",
                "provider": "anthropic",
                "diagnosis": content,
                "usage": {
                    "input_tokens": message.usage.input_tokens,
                    "output_tokens": message.usage.output_tokens,
                },
            }
        except Exception as e:
            return {
                "status": "error",
                "provider": "anthropic",
                "error": str(e),
            }

    def _mock_diagnose(self, error_log: str) -> dict[str, Any]:
        """Mock diagnosis for testing"""
        return {
            "status": "success",
            "provider": "mock",
            "diagnosis": f"Mock diagnosis for error log (length: {len(error_log)} chars)",
            "note": "This is a mock response. Configure OPENAI_API_KEY or ANTHROPIC_API_KEY for real AI diagnosis.",
        }


# Convenience function for quick diagnosis
def quick_diagnose(
    error_log: str,
    provider: AIProvider | None = None,
) -> dict[str, Any]:
    """
    Quick diagnosis helper

    Args:
        error_log: Error log content
        provider: AI provider (auto-detected if None)

    Returns:
        Diagnosis results
    """
    if provider is None:
        # Auto-detect provider
        if os.getenv("OPENAI_API_KEY"):
            provider = AIProvider.OPENAI
        elif os.getenv("ANTHROPIC_API_KEY"):
            provider = AIProvider.ANTHROPIC
        else:
            provider = AIProvider.MOCK

    client = AIClient(provider)
    return client.diagnose_error(error_log)
